package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.NcUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.NcWorkMapper;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 标准农事 服务层实现
 *
 * @author ruoyi
 * @date 2019-07-28
 */
@Service
public class NcWorkServiceImpl implements INcWorkService {
    @Autowired
    private NcWorkMapper ncWorkMapper;

    @Autowired
    private INcPlanService ncPlanService;

    @Autowired
    private INcStageService stageService;

    @Autowired
    private INcStandardService ncStandardService;

    @Autowired
    private INcWorkMirrorService workMirrorService;

    @Autowired
    private INcStageMirrorService stageMirrorService;

    /**
     * 查询标准农事信息
     *
     * @param workId 标准农事ID
     * @return 标准农事信息
     */
    @Override
    public NcWork selectNcWorkById(Long workId) {
        return ncWorkMapper.selectNcWorkById(workId);
    }

    /**
     * 查询标准农事列表
     *
     * @param ncWork 标准农事信息
     * @return 标准农事集合
     */
    @Override
    public List<NcWork> selectNcWorkList(NcWork ncWork) {
        return ncWorkMapper.selectNcWorkList(ncWork);
    }

    /**
     * 新增标准农事
     *
     * @param ncWork 标准农事信息
     * @return 结果
     */
    @Override
    public int insertNcWork(NcWork ncWork) {
        return ncWorkMapper.insertNcWork(ncWork);
    }

    /**
     * 修改标准农事
     *
     * @param ncWork 标准农事信息
     * @return 结果
     */
    @Override
    public int updateNcWork(NcWork ncWork) {
        return ncWorkMapper.updateNcWork(ncWork);
    }

    /**
     * 删除标准农事对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteNcWorkByIds(String ids) {
        return ncWorkMapper.deleteNcWorkByIds(Convert.toStrArray(ids));
    }

    /*获取温室或者育苗当天的工作*/
    @Override
    public List<NcWorkMirror> listTodays(NcWork ncWork, SysUser sysUser) {
        String today = DateUtils.parseDateToStr("yyyy-MM-dd", new Date());
        /*step1 获取当前所有的进入生产的计划*/
        NcPlan plan = new NcPlan();
        plan.setStatus("2,3");//已生计划单 但尚未完成的、在执行的计划
        plan.getParams().put("today", today);
        if (ncWork.getParams().get("planType") != null) {
            plan.setPlanType(Integer.parseInt("" + ncWork.getParams().get("planType")));
        }
        List<NcPlan> plans = ncPlanService.selectNcPlanList(plan);


        /*step2 根据从计划获取的镜像标准id获取标准 及标准下的阶段 和工作*/

        for (NcPlan p : plans) {
            //标准
            NcStandard standard = ncStandardService.selectNcStandardById(p.getStandardId());
            if (standard != null) {
                p.setStandard(standard);

                NcStageMirror st = new NcStageMirror();
                st.setPlanId(p.getPlanId());
//                st.setStageStatus("2");//正在执行的阶段
                List<NcStageMirror> stages = stageMirrorService.selectNcStageMirrorList(st);
                p.setStages(stages);
            }
        }
        List<NcWorkMirror> result = new ArrayList<>();
        /*当天需要确认完成的阶段*/
        List<NcStageMirror> todayStages = new ArrayList<>();
        /*获取当天的农事*/
        for (NcPlan p : plans) {
            Date start = p.getPlanTime();
            List<NcStageMirror> stages = p.getStages();
            if (stages != null) {
                for (NcStageMirror st : stages) {
                    //获取这个工作的实际要执行的时间
                    if ("2".equals(st.getStageStatus())) {
                        if (isTodayStage(start, stages, st)) {
                            todayStages.add(st);
                        }


                        for (NcWorkMirror w : st.getWorks()) {
                            if (w.getWorkId() != null) {
                                //获取这个工作的实际要执行的时间
                                if (isTodayWork(start, stages, st, w, today)) {
                                    w.setType("1");//工作
                                    w.setStageMirrorId(st.getStageMirrorId());
                                    result.add(w);
                                }
                            }
                        }
                    }
                }
            }
        }

        for (NcStageMirror st : todayStages) {
            NcWorkMirror wm = new NcWorkMirror();
            wm.setStageId(st.getStageId());
            wm.setType("2");//阶段
            wm.setPlanId(st.getPlanId());
            wm.setWorkStatus("2");
            wm.setWorkDetail(st.getStageDetail());
            wm.setWorkName(st.getStageName());
            wm.setStageMirrorId(st.getStageMirrorId());
            wm.setWorkDate(st.getWorkDate());
            wm.setWorkEndDate(st.getWorkEndDate());
            result.add(wm);

        }

        return result;
    }

    /*获取温室或者育苗正在执行的阶段*/
    @Override
    public List<NcStageMirror> listOnExe(NcStageMirror ncWork, SysUser sysUser) {

        NcStageMirror st = new NcStageMirror();
        st.setParams(ncWork.getParams());
        List<NcStageMirror> stages = stageMirrorService.selectNcStageMirrorList(st);

        List<NcStageMirror> result = new ArrayList<>();
        for (NcStageMirror sgt : stages) {
            if ("2".equals(sgt.getStageStatus())) {
                NcStageMirror temp = new NcStageMirror();
                temp.setPlanId(sgt.getPlanId());

                calStartEnd(sgt.getPlanTime(), stageMirrorService.selectNcStageMirrorList(temp), sgt);
                result.add(sgt);
            }
        }
        return result;
    }

    @Override
    public List<NcPlan> listpreExe(NcPlan plan, SysUser sysUser) {
        plan.setStatus("2");
        //计划已生成订单 但尚未开始的
        return ncPlanService.selectNcPlanList(plan);
    }

    /*获取这个工作的实际要执行的时间*/
    private boolean isTodayWork(Date start, List<NcStageMirror> stages, NcStageMirror st, NcWorkMirror w, String today) {
        if ("1".equals(w.getWorkStatus())) {
            return false;
        }

        int days = -1;
        for (NcStageMirror s : stages) {
            if (s.equals(st)) {
                break;
            } else {
                days += s.getStageDays();
            }
        }
        //以上days 是从计划开始到这个阶段所用时间  TODO 这样就需要有个镜像的标准  受实际的工作调整支配
        //1、如果是非周期性的
        if (w.getCycleDays() <= 0) {
            days += w.getWorkStart();
            Date d = DateUtils.addDays(start, days);
            if (today.equals(DateUtils.parseDateToStr("yyyy-MM-dd", d))) {
                w.setWorkDate(d);
                return true;
            }
            //100天前的 完成的工作
            if (NcUtils.differentDaysByDate(new Date(), d) <= 100 && NcUtils.differentDaysByDate(new Date(), d) >= 0) {
                w.setWorkDate(d);
                return true;
            }

        } else {
            //2、周期性的
            days += w.getWorkStart();
            List<Integer> list = new ArrayList<>();
            list.add(days);

            int cycleDays = w.getCycleDays();
            int left = st.getStageDays() - w.getWorkStart();
            int times = left / cycleDays;

            if (times > 0) {
                for (int i = 0; i < times; i++) {
                    days += cycleDays;
                    list.add(days);
                }
            }
            for (int i = 0; i < list.size(); i++) {
                Date d = DateUtils.addDays(start, list.get(i));
                if (today.equals(DateUtils.parseDateToStr("yyyy-MM-dd", d))) {
                    w.setWorkDate(d);
                    return true;
                }
            }


        }
        return false;
    }


    /*是当天要执行确认结束的阶段*/
    private boolean isTodayStage(Date start, List<NcStageMirror> stages, NcStageMirror st) {


        int daye = -1;
        int days = 0;

        for (NcStageMirror s : stages) {
            daye += s.getStageDays();
            if (s.equals(st)) {
                break;
            } else {
                days += s.getStageDays();
            }
        }
        Date de = DateUtils.addDays(start, daye);
        Date ds = DateUtils.addDays(start, days);
        /*只要是在执行的结束时间小于等于当天的*/
        if (NcUtils.differentDaysByDate(new Date(), de) >= 0) {
//            st.setWorkEndDate(ds);
            st.setWorkDate(de);
            return true;
        }
        return false;
    }

    /*填上开始时间 和结束时间*/
    private void calStartEnd(Date start, List<NcStageMirror> stages, NcStageMirror st) {

        int daye = -1;
        int days = 0;

        for (NcStageMirror s : stages) {
            daye += s.getStageDays();
            if (s.getStageId().equals(st.getStageId())) {
                break;
            } else {
                days += s.getStageDays();
            }
        }
        Date de = DateUtils.addDays(start, daye);
        Date ds = DateUtils.addDays(start, days);
        /*只要是在执行的结束时间小于等于当天的*/
        st.setWorkEndDate(de);
        st.setWorkDate(ds);
    }
}
